/**
 * Title:       Node.java
 * Copyright:   Copyright (c) 1996-2004 The Agent Factory Working Group. All rights reserved.
 * Licence:     This file is free software; you can redistribute it and/or modify
 *              it under the terms of the GNU Lesser General Public License as published by
 *              the Free Software Foundation; either version 2.1, or (at your option)
 *              any later version.
 *
 *              This file is distributed in the hope that it will be useful,
 *              but WITHOUT ANY WARRANTY; without even the implied warranty of
 *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *              GNU Lesser General Public License for more details.
 *
 *              You should have received a copy of the GNU Lesser General Public License
 *              along with Agent Factory; see the file COPYING.  If not, write to
 *              the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 *              Boston, MA 02111-1307, USA.
 */

package com.agentfactory.platform.mts;

import java.util.HashMap;
import java.util.ArrayList;
import java.util.StringTokenizer;
/**
 *
 * @author  Rem Collier
 */
public class Node {
    private String name;
    private HashMap arguments;
    private Object contents;
    
    /**
     * Factory method that creates an ArrayList of Node objects from some
     * given XML in string format.
     * @param xml the xml string to be parsed.
     * @return an ArrayList
     */
    public static Object parseXML(String xml) {
        ArrayList list = new ArrayList();
        xml = removeUnwanted(xml);
        
        int startIndex = xml.indexOf("<");
        if (startIndex == -1) {
            list.add(xml);
        }
        
        int endIndex = xml.indexOf(">", startIndex);
        while ((endIndex > -1) && (startIndex > -1)) {
            String commandLine = xml.substring(startIndex+1, endIndex).trim();
            StringTokenizer tok = new StringTokenizer(commandLine, " ");
            String name = tok.nextToken();

            boolean hasContent = true;
            if (commandLine.endsWith("/")) {
                commandLine = commandLine.substring(0, commandLine.length()-1).trim();
                hasContent = false;
            }

            int index = 0;
            String argument;
            HashMap arguments = new HashMap();
            while (tok.hasMoreTokens()) {
                argument = tok.nextToken();
                index = argument.indexOf("=");
                arguments.put(argument.substring(0,index), argument.substring(index+1));
            }

            // Contents node!
            Object contents = null;

            if (hasContent) {
                int nextStartIndex = xml.indexOf("</"+name, endIndex);
                String nodeContents = xml.substring(endIndex+1, nextStartIndex).trim();
                contents = parseXML(nodeContents);
                endIndex = xml.indexOf(">", nextStartIndex);
            }

            list.add(new Node(name, arguments, contents));
            startIndex = xml.indexOf("<", endIndex);
            endIndex = xml.indexOf(">", startIndex);
        }
        
        return list;
    }
    
    /**
     * Private method used by the factory method to remove any unwanted
     * expressions from the XML string.  These include <?xml... ?>
     * and <!...>
     *
     * @param xml the string to be modified.
     * @return the modified string.
     */
    private static String removeUnwanted(String xml) {
        String newString = xml;
        int index2, index = xml.indexOf("<?");
        while (index > -1) {
            index2 = newString.indexOf("?>", index);
            newString = xml.substring(0, index) + xml.substring(index2+2);
            index = newString.indexOf("<?");
        }
        
        index = xml.indexOf("<!");
        while (index > -1) {
            index2 = newString.indexOf(">", index);
            newString = xml.substring(0, index) + xml.substring(index2+1);
            index = newString.indexOf("<!");
        }
        
        return newString;
    }

    /** Creates a new instance of Node */
    private Node(String name, HashMap arguments, Object contents) {
        this.name = name;
        this.arguments = arguments;
        this.contents = contents;
    }
    
    public String getName() {
        return name;
    }
    
    public String getParameter(String key) {
        return (String) arguments.get(key);
    }
    
    public Object getContents() {
        return contents;
    }
    
    public int numChildren() {
        if (contents instanceof String) {
            return 1;
        } else {
            return ((java.util.ArrayList) contents).size();
        }
    }
    
    public Object getChild(int index) {
        if (contents instanceof String) {
            if (index == 0) {
                return contents;
            } else {
                throw new IndexOutOfBoundsException();
            }
        } else {
            return ((java.util.ArrayList) contents).get(index);
        }
    }
    
    public String toString() {
        StringBuffer buf = new StringBuffer();
        buf.append("[").append(name);
        
        Object key = null;
        java.util.Iterator it = arguments.keySet().iterator();
        while (it.hasNext()) {
            key = it.next();
            buf.append(",").append(key).append("=").append(arguments.get(key));
        }
        
        buf.append("] - ").append(contents);
        
        return buf.toString();
    }
}
